Bundle vcpu_time and vcpu_info structures together into a single
authorkaf24@firebug.cl.cam.ac.uk <kaf24@firebug.cl.cam.ac.uk>
Mon, 28 Nov 2005 18:48:54 +0000 (19:48 +0100)
committerkaf24@firebug.cl.cam.ac.uk <kaf24@firebug.cl.cam.ac.uk>
Mon, 28 Nov 2005 18:48:54 +0000 (19:48 +0100)
structure that is 64 bytes on x86. This ensures that indexing into
the array is fast (power-of-two size) and that accesses are cache
friendly (cache line size is usually 32 or 64 bytes).

Rename vcpu_data to vcpu_info, vcpu_time to vcpu_info.time.

Signed-off-by: Keir Fraser <keir@xensource.com>
24 files changed:
linux-2.6-xen-sparse/arch/ia64/xen/drivers/evtchn_ia64.c
linux-2.6-xen-sparse/arch/xen/i386/kernel/entry.S
linux-2.6-xen-sparse/arch/xen/i386/kernel/time.c
linux-2.6-xen-sparse/arch/xen/i386/mm/fault.c
linux-2.6-xen-sparse/arch/xen/kernel/evtchn.c
linux-2.6-xen-sparse/arch/xen/x86_64/kernel/xen_entry.S
linux-2.6-xen-sparse/arch/xen/x86_64/mm/fault.c
linux-2.6-xen-sparse/include/asm-xen/asm-i386/system.h
linux-2.6-xen-sparse/include/asm-xen/asm-x86_64/system.h
linux-2.6-xen-sparse/include/asm-xen/evtchn.h
tools/libxc/xc_linux_build.c
tools/libxc/xc_linux_restore.c
tools/libxc/xc_vmx_build.c
xen/arch/ia64/vmx/vmx_hypercall.c
xen/arch/ia64/xen/domain.c
xen/arch/x86/domain.c
xen/arch/x86/domain_build.c
xen/arch/x86/setup.c
xen/arch/x86/time.c
xen/common/schedule.c
xen/include/public/arch-x86_32.h
xen/include/public/arch-x86_64.h
xen/include/public/trace.h
xen/include/public/xen.h

index 26ad8c3395baac08332fbf148428065929f8a71e..e8f9f863e90d07b236c68f102d40c1104f2a7e6d 100644 (file)
@@ -155,7 +155,7 @@ irqreturn_t evtchn_interrupt(int irq, void *dev_id, struct pt_regs *regs)
     unsigned int   l1i, l2i, port;
     irqreturn_t (*handler)(int, void *, struct pt_regs *);
     shared_info_t *s = HYPERVISOR_shared_info;
-    vcpu_info_t   *vcpu_info = &s->vcpu_data[smp_processor_id()];
+    vcpu_info_t   *vcpu_info = &s->vcpu_info[smp_processor_id()];
 
     vcpu_info->evtchn_upcall_mask = 1;
     vcpu_info->evtchn_upcall_pending = 0;
@@ -203,7 +203,7 @@ int evtchn_irq = 0xe9;
 void __init evtchn_init(void)
 {
     shared_info_t *s = HYPERVISOR_shared_info;
-    vcpu_info_t   *vcpu_info = &s->vcpu_data[smp_processor_id()];
+    vcpu_info_t   *vcpu_info = &s->vcpu_info[smp_processor_id()];
 
 #if 0
     int ret;
index ad38d736c7a891333652e9d183ed27e0c31ebf38..6522f7a249a52130f42d91961b26ba17562d2bfb 100644 (file)
@@ -81,7 +81,7 @@ VM_MASK               = 0x00020000
 #define evtchn_upcall_pending          /* 0 */
 #define evtchn_upcall_mask             1
 
-#define sizeof_vcpu_shift              4
+#define sizeof_vcpu_shift              6
 
 #ifdef CONFIG_SMP
 #define preempt_disable(reg)   incl TI_preempt_count(reg)
index 4e363e55a0d6c9f60c26ae31727ecd7f79aa54d5..915f7f033a669ca296df29b79f9eadd2ecf4b21f 100644 (file)
@@ -204,7 +204,8 @@ static inline u64 scale_delta(u64 delta, u32 mul_frac, int shift)
 void init_cpu_khz(void)
 {
        u64 __cpu_khz = 1000000ULL << 32;
-       struct vcpu_time_info *info = &HYPERVISOR_shared_info->vcpu_time[0];
+       struct vcpu_time_info *info;
+       info = &HYPERVISOR_shared_info->vcpu_info[0].time;
        do_div(__cpu_khz, info->tsc_to_system_mul);
        if ( info->tsc_shift < 0 )
                cpu_khz = __cpu_khz << -info->tsc_shift;
@@ -284,7 +285,7 @@ static void get_time_values_from_xen(void)
        struct vcpu_time_info   *src;
        struct shadow_time_info *dst;
 
-       src = &s->vcpu_time[smp_processor_id()];
+       src = &s->vcpu_info[smp_processor_id()].time;
        dst = &per_cpu(shadow_time, smp_processor_id());
 
        do {
@@ -306,7 +307,7 @@ static inline int time_values_up_to_date(int cpu)
        struct vcpu_time_info   *src;
        struct shadow_time_info *dst;
 
-       src = &HYPERVISOR_shared_info->vcpu_time[cpu]; 
+       src = &HYPERVISOR_shared_info->vcpu_info[cpu].time;
        dst = &per_cpu(shadow_time, cpu); 
 
        return (dst->version == src->version);
index df9b971c875f2f53efee2a876df33fc6ba97472b..23b05563470830d2a6a8ef5971722f2afa7de4a4 100644 (file)
@@ -291,7 +291,7 @@ fastcall void do_page_fault(struct pt_regs *regs, unsigned long error_code)
        int write;
        siginfo_t info;
 
-       address = HYPERVISOR_shared_info->vcpu_data[
+       address = HYPERVISOR_shared_info->vcpu_info[
                smp_processor_id()].arch.cr2;
 
        /* Set the "privileged fault" bit to something sane. */
index c5ddef540b59c881a65d35babb69888844f0bcf9..7ebe3f5e5840858eefd1a18d4f9acdad094fd5ee 100644 (file)
@@ -154,7 +154,7 @@ asmlinkage void evtchn_do_upcall(struct pt_regs *regs)
        unsigned int   l1i, l2i, port;
        int            irq, cpu = smp_processor_id();
        shared_info_t *s = HYPERVISOR_shared_info;
-       vcpu_info_t   *vcpu_info = &s->vcpu_data[cpu];
+       vcpu_info_t   *vcpu_info = &s->vcpu_info[cpu];
 
        vcpu_info->evtchn_upcall_pending = 0;
 
index bba3950aedab7db361f5d6ae9eaaafb4c0a759c3..9b42d155663715ee078effed09ae8a52c1f6e927 100644 (file)
@@ -5,7 +5,7 @@
 #define evtchn_upcall_pending          0
 #define evtchn_upcall_mask             1
 
-#define sizeof_vcpu_shift              5
+#define sizeof_vcpu_shift              6
 
 #ifdef CONFIG_SMP
 //#define preempt_disable(reg) incl threadinfo_preempt_count(reg)
index 1c76222721424f8d46e1c88c579ebcaaa55518c1..97e6ea18958af761434505bef1207f5c3afa6133 100644 (file)
@@ -344,7 +344,7 @@ asmlinkage void do_page_fault(struct pt_regs *regs, unsigned long error_code)
 #endif
 
        /* get the address */
-       address = HYPERVISOR_shared_info->vcpu_data[
+       address = HYPERVISOR_shared_info->vcpu_info[
                smp_processor_id()].arch.cr2;
 
        if (notify_die(DIE_PAGE_FAULT, "page fault", regs, error_code, 14,
index 592f20023ed391c4c008a5926970cf1c0d290092..0b6948437d78d11980ef61c0cd493f42aa2ebc50 100644 (file)
@@ -501,7 +501,7 @@ __asm__ __volatile__("6667:movl %1, %0\n6668:\n"                    \
 do {                                                                   \
        vcpu_info_t *_vcpu;                                             \
        preempt_disable();                                              \
-       _vcpu = &HYPERVISOR_shared_info->vcpu_data[smp_processor_id()]; \
+       _vcpu = &HYPERVISOR_shared_info->vcpu_info[smp_processor_id()]; \
        _vcpu->evtchn_upcall_mask = 1;                                  \
        preempt_enable_no_resched();                                    \
        barrier();                                                      \
@@ -512,7 +512,7 @@ do {                                                                        \
        vcpu_info_t *_vcpu;                                             \
        barrier();                                                      \
        preempt_disable();                                              \
-       _vcpu = &HYPERVISOR_shared_info->vcpu_data[smp_processor_id()]; \
+       _vcpu = &HYPERVISOR_shared_info->vcpu_info[smp_processor_id()]; \
        _vcpu->evtchn_upcall_mask = 0;                                  \
        barrier(); /* unmask then check (avoid races) */                \
        if ( unlikely(_vcpu->evtchn_upcall_pending) )                   \
@@ -524,7 +524,7 @@ do {                                                                        \
 do {                                                                   \
        vcpu_info_t *_vcpu;                                             \
        preempt_disable();                                              \
-       _vcpu = &HYPERVISOR_shared_info->vcpu_data[smp_processor_id()]; \
+       _vcpu = &HYPERVISOR_shared_info->vcpu_info[smp_processor_id()]; \
        (x) = _vcpu->evtchn_upcall_mask;                                \
        preempt_enable();                                               \
 } while (0)
@@ -534,7 +534,7 @@ do {                                                                        \
        vcpu_info_t *_vcpu;                                             \
        barrier();                                                      \
        preempt_disable();                                              \
-       _vcpu = &HYPERVISOR_shared_info->vcpu_data[smp_processor_id()]; \
+       _vcpu = &HYPERVISOR_shared_info->vcpu_info[smp_processor_id()]; \
        if ((_vcpu->evtchn_upcall_mask = (x)) == 0) {                   \
                barrier(); /* unmask then check (avoid races) */        \
                if ( unlikely(_vcpu->evtchn_upcall_pending) )           \
@@ -550,7 +550,7 @@ do {                                                                        \
 do {                                                                   \
        vcpu_info_t *_vcpu;                                             \
        preempt_disable();                                              \
-       _vcpu = &HYPERVISOR_shared_info->vcpu_data[smp_processor_id()]; \
+       _vcpu = &HYPERVISOR_shared_info->vcpu_info[smp_processor_id()]; \
        (x) = _vcpu->evtchn_upcall_mask;                                \
        _vcpu->evtchn_upcall_mask = 1;                                  \
        preempt_enable_no_resched();                                    \
@@ -568,7 +568,7 @@ do {                                                                        \
 ({     int ___x;                                                       \
        vcpu_info_t *_vcpu;                                             \
        preempt_disable();                                              \
-       _vcpu = &HYPERVISOR_shared_info->vcpu_data[smp_processor_id()]; \
+       _vcpu = &HYPERVISOR_shared_info->vcpu_info[smp_processor_id()]; \
        ___x = (_vcpu->evtchn_upcall_mask != 0);                        \
        preempt_enable_no_resched();                                    \
        ___x; })
index bbecfc56ed12cf5d364f575255a8c9bdcc69d8e4..0b485568ac82d1e74081da749078199d900076e6 100644 (file)
@@ -325,7 +325,7 @@ static inline unsigned long __cmpxchg(volatile void *ptr, unsigned long old,
 do {                                                                   \
        vcpu_info_t *_vcpu;                                             \
        preempt_disable();                                              \
-       _vcpu = &HYPERVISOR_shared_info->vcpu_data[smp_processor_id()]; \
+       _vcpu = &HYPERVISOR_shared_info->vcpu_info[smp_processor_id()]; \
        _vcpu->evtchn_upcall_mask = 1;                                  \
        preempt_enable_no_resched();                                    \
        barrier();                                                      \
@@ -336,7 +336,7 @@ do {                                                                        \
        vcpu_info_t *_vcpu;                                             \
        barrier();                                                      \
        preempt_disable();                                              \
-       _vcpu = &HYPERVISOR_shared_info->vcpu_data[smp_processor_id()]; \
+       _vcpu = &HYPERVISOR_shared_info->vcpu_info[smp_processor_id()]; \
        _vcpu->evtchn_upcall_mask = 0;                                  \
        barrier(); /* unmask then check (avoid races) */                \
        if ( unlikely(_vcpu->evtchn_upcall_pending) )                   \
@@ -348,7 +348,7 @@ do {                                                                        \
 do {                                                                   \
        vcpu_info_t *_vcpu;                                             \
        preempt_disable();                                              \
-       _vcpu = &HYPERVISOR_shared_info->vcpu_data[smp_processor_id()]; \
+       _vcpu = &HYPERVISOR_shared_info->vcpu_info[smp_processor_id()]; \
        (x) = _vcpu->evtchn_upcall_mask;                                \
        preempt_enable();                                               \
 } while (0)
@@ -358,7 +358,7 @@ do {                                                                        \
        vcpu_info_t *_vcpu;                                             \
        barrier();                                                      \
        preempt_disable();                                              \
-       _vcpu = &HYPERVISOR_shared_info->vcpu_data[smp_processor_id()]; \
+       _vcpu = &HYPERVISOR_shared_info->vcpu_info[smp_processor_id()]; \
        if ((_vcpu->evtchn_upcall_mask = (x)) == 0) {                   \
                barrier(); /* unmask then check (avoid races) */        \
                if ( unlikely(_vcpu->evtchn_upcall_pending) )           \
@@ -374,7 +374,7 @@ do {                                                                        \
 do {                                                                   \
        vcpu_info_t *_vcpu;                                             \
        preempt_disable();                                              \
-       _vcpu = &HYPERVISOR_shared_info->vcpu_data[smp_processor_id()]; \
+       _vcpu = &HYPERVISOR_shared_info->vcpu_info[smp_processor_id()]; \
        (x) = _vcpu->evtchn_upcall_mask;                                \
        _vcpu->evtchn_upcall_mask = 1;                                  \
        preempt_enable_no_resched();                                    \
@@ -394,7 +394,7 @@ void cpu_idle_wait(void);
 ({     int ___x;                                                       \
        vcpu_info_t *_vcpu;                                             \
        preempt_disable();                                              \
-       _vcpu = &HYPERVISOR_shared_info->vcpu_data[smp_processor_id()]; \
+       _vcpu = &HYPERVISOR_shared_info->vcpu_info[smp_processor_id()]; \
        ___x = (_vcpu->evtchn_upcall_mask != 0);                        \
        preempt_enable_no_resched();                                    \
        ___x; })
index 82b13cef549f1e134354d7ab27cdbcd15902d0ee..788e8d7b5ec78f9ccc3244bd2da2adf83db26639 100644 (file)
@@ -102,7 +102,7 @@ static inline void mask_evtchn(int port)
 static inline void unmask_evtchn(int port)
 {
        shared_info_t *s = HYPERVISOR_shared_info;
-       vcpu_info_t *vcpu_info = &s->vcpu_data[smp_processor_id()];
+       vcpu_info_t *vcpu_info = &s->vcpu_info[smp_processor_id()];
 
        synch_clear_bit(port, &s->evtchn_mask[0]);
 
index d61ecfa549cb17ce8480066c6755ac6b0e0435a1..1afea3cb39b13320a25562164ad5c2f7da8c7e22 100644 (file)
@@ -657,7 +657,7 @@ static int setup_guest(int xc_handle,
     memset(shared_info, 0, sizeof(shared_info_t));
     /* Mask all upcalls... */
     for ( i = 0; i < MAX_VIRT_CPUS; i++ )
-        shared_info->vcpu_data[i].evtchn_upcall_mask = 1;
+        shared_info->vcpu_info[i].evtchn_upcall_mask = 1;
 
     munmap(shared_info, PAGE_SIZE);
 
index 674915904c7652ed5345ab016b5caebd108edd53..f25c185abcc4a4c1b7b206c42c603edb89fcef13 100644 (file)
@@ -671,7 +671,7 @@ int xc_linux_restore(int xc_handle, int io_fd,
     memset(&(shared_info->evtchn_pending[0]), 0,
            sizeof (shared_info->evtchn_pending));
     for ( i = 0; i < MAX_VIRT_CPUS; i++ )
-        shared_info->vcpu_data[i].evtchn_pending_sel = 0;
+        shared_info->vcpu_info[i].evtchn_pending_sel = 0;
 
     /* Copy saved contents of shared-info page. No checking needed. */
     page = xc_map_foreign_range(
index 47cc1271cb02ccc23a214f0d19c225e73b951e87..2146c83fc8396a27a1c70dcaa27cf1a5854f1b57 100644 (file)
@@ -524,7 +524,7 @@ static int setup_guest(int xc_handle,
     memset(shared_info, 0, sizeof(shared_info_t));
     /* Mask all upcalls... */
     for ( i = 0; i < MAX_VIRT_CPUS; i++ )
-        shared_info->vcpu_data[i].evtchn_upcall_mask = 1;
+        shared_info->vcpu_info[i].evtchn_upcall_mask = 1;
 
     munmap(shared_info, PAGE_SIZE);
 
index 26f924196ed3cf72f910e09cd90b1707bda391fb..020c3e933f4060494d73d303bb2a5134c76d3ece 100644 (file)
@@ -198,7 +198,7 @@ static int do_set_shared_page(VCPU *vcpu, u64 gpa)
     if (o_info) {
        memcpy((void*)d->shared_info, (void*)o_info, PAGE_SIZE);
        for_each_vcpu(d, v) {
-               v->vcpu_info = &d->shared_info->vcpu_data[v->vcpu_id];
+               v->vcpu_info = &d->shared_info->vcpu_info[v->vcpu_id];
        }
        /* If original page belongs to xen heap, then relinguish back
         * to xen heap. Or else, leave to domain itself to decide.
index bca625d77b212f04a2e730bd618994bc5eb58b94..52c62d6f2468413c574068b22523e678c5164aeb 100644 (file)
@@ -205,7 +205,7 @@ void arch_do_createdomain(struct vcpu *v)
        printf("arch_vcpu_info=%p\n", d->vcpu[0].arch.privregs);
        memset(d->vcpu.arch.privregs, 0, PAGE_SIZE);
 #endif
-       v->vcpu_info = &(d->shared_info->vcpu_data[0]);
+       v->vcpu_info = &(d->shared_info->vcpu_info[0]);
 
        d->max_pages = (128UL*1024*1024)/PAGE_SIZE; // 128MB default // FIXME
 
@@ -867,7 +867,7 @@ int construct_dom0(struct domain *d,
 
        /* Mask all upcalls... */
        for ( i = 1; i < MAX_VIRT_CPUS; i++ )
-           d->shared_info->vcpu_data[i].evtchn_upcall_mask = 1;
+           d->shared_info->vcpu_info[i].evtchn_upcall_mask = 1;
 
 #ifdef VALIDATE_VT 
        /* Construct a frame-allocation list for the initial domain, since these
@@ -997,7 +997,7 @@ int construct_domU(struct domain *d,
 
        /* Mask all upcalls... */
        for ( i = 0; i < MAX_VIRT_CPUS; i++ )
-               d->shared_info->vcpu_data[i].evtchn_upcall_mask = 1;
+               d->shared_info->vcpu_info[i].evtchn_upcall_mask = 1;
 
        /* Copy the OS image. */
        printk("calling loaddomainelfimage(%p,%p)\n",d,image_start);
index 54d166485cdc7014b0b683d9ffa24ed0e5411433..b24432336972f0d1d91d8aff3988fb0bba4de673 100644 (file)
@@ -266,7 +266,7 @@ void arch_do_createdomain(struct vcpu *v)
 
     d->shared_info = alloc_xenheap_page();
     memset(d->shared_info, 0, PAGE_SIZE);
-    v->vcpu_info = &d->shared_info->vcpu_data[v->vcpu_id];
+    v->vcpu_info = &d->shared_info->vcpu_info[v->vcpu_id];
     v->cpumap = CPUMAP_RUNANYWHERE;
     SHARE_PFN_WITH_DOMAIN(virt_to_page(d->shared_info), d);
 
index b83ea2c47c1b7d0e028ec31d09f9d3a876afcf85..3f96396877acd95ee3732a10347b899b79daefa2 100644 (file)
@@ -597,7 +597,7 @@ int construct_dom0(struct domain *d,
 
     /* Mask all upcalls... */
     for ( i = 0; i < MAX_VIRT_CPUS; i++ )
-        d->shared_info->vcpu_data[i].evtchn_upcall_mask = 1;
+        d->shared_info->vcpu_info[i].evtchn_upcall_mask = 1;
 
     for ( i = 1; i < num_online_cpus(); i++ )
         (void)alloc_vcpu(d, i, i);
index 01ed11af3f05d94f37ecee356aaf9d4e00b0d2b6..625a2a0d5288bb5a2eefb33757408124c9058eab 100644 (file)
@@ -432,7 +432,7 @@ void __init __start_xen(multiboot_info_t *mbi)
 
     BUG_ON(sizeof(start_info_t) > PAGE_SIZE);
     BUG_ON(sizeof(shared_info_t) > PAGE_SIZE);
-    BUG_ON(sizeof(vcpu_info_t) != (sizeof(unsigned long) * 4));
+    BUG_ON(sizeof(vcpu_info_t) != 64);
 
     init_frametable();
 
index b5f7023bd6dbf9fc374f2c0fe5f5404cfb200c2e..7e7c40fca1e0c72aa77fd606ed87e9c21549cc33 100644 (file)
@@ -683,8 +683,11 @@ static inline void version_update_end(u32 *version)
 
 static inline void __update_dom_time(struct vcpu *v)
 {
-    struct cpu_time       *t = &cpu_time[smp_processor_id()];
-    struct vcpu_time_info *u = &v->domain->shared_info->vcpu_time[v->vcpu_id];
+    struct cpu_time       *t;
+    struct vcpu_time_info *u;
+
+    t = &cpu_time[smp_processor_id()];
+    u = &v->domain->shared_info->vcpu_info[v->vcpu_id].time;
 
     version_update_begin(&u->version);
 
@@ -698,7 +701,7 @@ static inline void __update_dom_time(struct vcpu *v)
 
 void update_dom_time(struct vcpu *v)
 {
-    if ( v->domain->shared_info->vcpu_time[v->vcpu_id].tsc_timestamp != 
+    if ( v->domain->shared_info->vcpu_info[v->vcpu_id].time.tsc_timestamp != 
          cpu_time[smp_processor_id()].local_tsc_stamp )
         __update_dom_time(v);
 }
index 7a0b6223731e9403721b57f2c509374141e12264..d74b3c837027b67583249e1abde58baeaee3c9b8 100644 (file)
@@ -115,7 +115,7 @@ struct vcpu *alloc_vcpu(
 
     if ( vcpu_id != 0 )
     {
-        v->vcpu_info = &d->shared_info->vcpu_data[vcpu_id];
+        v->vcpu_info = &d->shared_info->vcpu_info[vcpu_id];
         d->vcpu[v->vcpu_id-1]->next_in_list = v;
         set_bit(_VCPUF_down, &v->vcpu_flags);
     }
index b11c4821188521e554682e02b2d3e9440b0b013f..9d7b69f694e22c176ab8ec7c21eab0889200ad80 100644 (file)
@@ -134,7 +134,7 @@ typedef struct arch_shared_info {
 
 typedef struct {
     unsigned long cr2;
-    unsigned long pad; /* sizeof(vcpu_info_t) == 16 */
+    unsigned long pad[5]; /* sizeof(vcpu_info_t) == 64 */
 } arch_vcpu_info_t;
 
 #endif
index e53df602eae2fb606d8845a385d70111ccd211ec..5e3b6a7671ee17a5ef86392bed6c771da4da8839 100644 (file)
@@ -203,7 +203,7 @@ typedef struct arch_shared_info {
 
 typedef struct {
     unsigned long cr2;
-    unsigned long pad; /* sizeof(vcpu_info_t) == 32 */
+    unsigned long pad; /* sizeof(vcpu_info_t) == 64 */
 } arch_vcpu_info_t;
 
 #endif /* !__ASSEMBLY__ */
index b9f139444ea73d629b36b2e3fc38f49ff30463c8..cba4b261cab0fe7281ab3b071b83869ef2f11a73 100644 (file)
@@ -72,8 +72,8 @@ struct t_rec {
  * field, indexes into an array of struct t_rec's.
  */
 struct t_buf {
-    unsigned int  cons;      /* Next item to be consumed by control tools. */
-    unsigned int  prod;      /* Next item to be produced by Xen.           */
+    uint32_t cons;      /* Next item to be consumed by control tools. */
+    uint32_t prod;      /* Next item to be produced by Xen.           */
     /* 'nr_recs' records follow immediately after the meta-data header.    */
 };
 
index 2259fc3ba007092cad9c50da21a35d8197ffcd2f..b27206caffe9cdcf1ce2d64bd8de8d158c9a2a19 100644 (file)
@@ -266,10 +266,31 @@ typedef struct
  */
 #define NR_EVENT_CHANNELS (sizeof(unsigned long) * sizeof(unsigned long) * 64)
 
-/*
- * Per-VCPU information goes here. This will be cleaned up more when Xen 
- * actually supports multi-VCPU guests.
- */
+typedef struct vcpu_time_info {
+    /*
+     * Updates to the following values are preceded and followed by an
+     * increment of 'version'. The guest can therefore detect updates by
+     * looking for changes to 'version'. If the least-significant bit of
+     * the version number is set then an update is in progress and the guest
+     * must wait to read a consistent set of values.
+     * The correct way to interact with the version number is similar to
+     * Linux's seqlock: see the implementations of read_seqbegin/read_seqretry.
+     */
+    uint32_t version;
+    uint32_t pad0;
+    uint64_t tsc_timestamp;   /* TSC at last update of time vals.  */
+    uint64_t system_time;     /* Time, in nanosecs, since boot.    */
+    /*
+     * Current system time:
+     *   system_time + ((tsc - tsc_timestamp) << tsc_shift) * tsc_to_system_mul
+     * CPU frequency (Hz):
+     *   ((10^9 << 32) / tsc_to_system_mul) >> tsc_shift
+     */
+    uint32_t tsc_to_system_mul;
+    int8_t   tsc_shift;
+    int8_t   pad1[3];
+} vcpu_time_info_t; /* 32 bytes */
+
 typedef struct vcpu_info {
     /*
      * 'evtchn_upcall_pending' is written non-zero by Xen to indicate
@@ -300,39 +321,15 @@ typedef struct vcpu_info {
     uint8_t evtchn_upcall_mask;
     unsigned long evtchn_pending_sel;
     arch_vcpu_info_t arch;
-} vcpu_info_t;
-
-typedef struct vcpu_time_info {
-    /*
-     * Updates to the following values are preceded and followed by an
-     * increment of 'version'. The guest can therefore detect updates by
-     * looking for changes to 'version'. If the least-significant bit of
-     * the version number is set then an update is in progress and the guest
-     * must wait to read a consistent set of values.
-     * The correct way to interact with the version number is similar to
-     * Linux's seqlock: see the implementations of read_seqbegin/read_seqretry.
-     */
-    uint32_t version;
-    uint64_t tsc_timestamp;   /* TSC at last update of time vals.  */
-    uint64_t system_time;     /* Time, in nanosecs, since boot.    */
-    /*
-     * Current system time:
-     *   system_time + ((tsc - tsc_timestamp) << tsc_shift) * tsc_to_system_mul
-     * CPU frequency (Hz):
-     *   ((10^9 << 32) / tsc_to_system_mul) >> tsc_shift
-     */
-    uint32_t tsc_to_system_mul;
-    int8_t  tsc_shift;
-} vcpu_time_info_t;
+    vcpu_time_info_t time;
+} vcpu_info_t; /* 64 bytes (x86) */
 
 /*
  * Xen/kernel shared data -- pointer provided in start_info.
  * NB. We expect that this struct is smaller than a page.
  */
 typedef struct shared_info {
-    vcpu_info_t vcpu_data[MAX_VIRT_CPUS];
-
-    vcpu_time_info_t vcpu_time[MAX_VIRT_CPUS];
+    vcpu_info_t vcpu_info[MAX_VIRT_CPUS];
 
     /*
      * A domain can create "event channels" on which it can send and receive